package com.haiyou.common.id;

import org.apache.commons.lang3.Validate;

import com.haiyou.common.system.Properties;
import com.haiyou.common.util.random.ProbabilityUtils;

/**
 * 
 * 玩家id生成器 :玩家ID(18位)=env.id(环境id)+platform.id(大区4位)+player.id(玩家id10位)
 * @Description: id 生成器
 * @author xingyuan
 * @date 2022年9月20日 下午2:54:16
 */
public class IdCreator {

	//1000_0000_0000_0000_00L
	//     1000_0000_0000_00L
	//          1000_0000_00L
	
	/**
	 * dev 1000
	 * test 2000
	 * pro 3000
	 */
	public static final long ENV_ID = 1000_0000_0000_0000_00L;// 环境id (dev,pro,test 各个环境)

	public static final long PLATFORM_ID  = 1000_0000_0000_00L; // 大区id 渠道

	public static final long PLAYER_ID = 1000_0000_00L; // 玩家单位10位

	/**
	 * 配置的平台id(大渠道id)
	 * 
	 * @return
	 */
	public static Integer getPlatformId() {
		Integer platformId = Properties.platform_id();
		Validate.isTrue(platformId >= 1000 && platformId <= 9999, "平台id必须在1000~9999之间");
		return platformId;
	}
	
	/**
	 * 配置的服务器id,编号(小渠道id),也就是当前运行在哪个服
	 * 
	 * @return
	 */
	public static Integer getEnvId() {
		Integer envId = Properties.env_id();
		Validate.isTrue(envId >= 1000 && envId <= 9999, "环境1000~9999之间");
		return envId;
	}
	
	/**
	 * 直接使用当前配置的platformId和envId并且数据表偏移值为0生成id
	 * 
	 * @return
	 */
	public static long create() {
		return create(0, ProbabilityUtils.random(1111, 9999));
	}

	/**
	 * 直接使用当前配置的platformId和envId以及数据表配置的偏移量生成id
	 * 
	 * @param tableOffset 数据表偏移量(1~99)
	 * @return
	 */
	public static long create(int tableOffset) {
		return create(tableOffset, ProbabilityUtils.random(1111, 9999));
	}

	/**
	 * 直接使用当前配置的platformId和serverId生成id
	 * 
	 * @param tableOffset         数据表偏移量(1~99)
	 * @param clazzHashCodeOffset (0~9999)
	 * @return
	 */
	public static long create(int tableOffset, long clazzHashCodeOffset) {
		return create(getEnvId(),getPlatformId(), tableOffset, clazzHashCodeOffset);
	}

	/**
	 * 玩家id生成器 :玩家ID(18位)=env.id(环境id)+platform.id(大区4位)+player.id(玩家id10位)
	 * 
	 * @param platformId          平台id(4)
	 * @param serverId            服务器分区id(4)
	 * @param tableOffset         数据表偏移量(1~99)
	 * @param clazzHashCodeOffset (0~9999)
	 * @return
	 */
	public static long create(int envId, int platformId, int tableOffset, long clazzHashCodeOffset) {

		if (platformId < 1 || platformId > 9999) {
			throw new RuntimeException("1<= platformId <= 9999," + platformId);
		}
		if (envId < 1 || envId > 9999) {
			throw new RuntimeException("1<= envId <= 9999," + envId);
		}
		if (tableOffset != 0 && (tableOffset < 1 || tableOffset > 99)) {
			throw new RuntimeException("1<= tableOffset <= 99," + tableOffset);
		}
		if (clazzHashCodeOffset < 0 || clazzHashCodeOffset > 9999) {
			throw new RuntimeException("0<=clazzHashCodeOffset <= 9999," + clazzHashCodeOffset);
		}
		long id = 0;
		
		id = ENV_ID / 1000  * envId;
		id += PLATFORM_ID / 1000  * platformId;
		// 玩家id
		long _rid = PLAYER_ID;
		long rid = (tableOffset * (tableOffset > 0 && tableOffset < 10 ? _rid : _rid / 10)) + clazzHashCodeOffset;
		id += rid;
		Validate.isTrue(id > 0 && String.valueOf(id).length() == 18, "0<id<=9999_9999_9999999999", id);
		return id;
	}
}


